import java.awt.Point;
import java.awt.Polygon;
import java.util.Map;

import com.speljohan.rsbot.bot.Bot;
import com.speljohan.rsbot.event.events.ServerMessageEvent;
import com.speljohan.rsbot.event.listeners.ServerMessageListener;
import com.speljohan.rsbot.script.Calculations;
import com.speljohan.rsbot.script.Constants;
import com.speljohan.rsbot.script.Script;
import com.speljohan.rsbot.script.wrappers.RSInterface;
import com.speljohan.rsbot.script.wrappers.RSObject;
import com.speljohan.rsbot.script.wrappers.RSTile;

public class TSoulWars extends Script implements ServerMessageListener {

	int B_DeathX[] = new int[] { 1823, 1816, 1816, 1823 };
	int B_DeathY[] = new int[] { 3220, 3220, 3230, 3230 };
	Polygon B_Death = new Polygon(B_DeathX, B_DeathY, 4);

	int OutX[] = new int[] { 1886, 1890, 1894, 1898, 1904, 1897, 1899, 1895,
			1880, 1880, 1880 };
	int OutY[] = new int[] { 3182, 3181, 3179, 3180, 3172, 3166, 3162, 3157,
			3154, 3161, 3173 };
	Polygon Out = new Polygon(OutX, OutY, 11);

	int R_DeathX[] = new int[] { 1953, 1958, 1959, 1959, 1958, 1953, 1952, 1952 };
	int R_DeathY[] = new int[] { 3245, 3245, 3244, 3236, 3235, 3235, 3236, 3244 };
	Polygon R_Death = new Polygon(R_DeathX, R_DeathY, 8);

	public TSoulWars() {
		setParameter("author", "!@!@!");
		setParameter("version", 1.5);
		setParameter("name", "TSoulWars - Public");
		setParameter("category", "Combat");
		setParameter("description", disc());
	}

	public boolean atDoorTile(final RSTile loc, final String direction,
			final String action) {
		if (loc == null) {
			return false;
		}
		if (Bot.getClient().isMenuOpen()) {
			atMenu("Cancel");
		}
		Point t = null;
		if (direction.toLowerCase().startsWith("n")) {
			t = Calculations.tileToScreen(loc.getX(), loc.getY() + 1, .5, .1,
					40);
		} else if (direction.toLowerCase().startsWith("s")) {
			t = Calculations.tileToScreen(loc.getX(), loc.getY(), .5, .1, 40);
		} else if (direction.toLowerCase().startsWith("w")) {
			t = Calculations.tileToScreen(loc.getX(), loc.getY(), .1, .5, 40);
		} else if (direction.toLowerCase().startsWith("e")) {
			t = Calculations.tileToScreen(loc.getX() + 1, loc.getY(), .1, .5,
					40);
		}
		if (t == null) {
			return false;
		}
		clickMouse(t, 3, 3, false);
		return atMenu(action);
	}

	public boolean atPortal(final RSTile tile, final String action) {
		try {
			final Point location = Calculations.tileToScreen(tile.getX(), tile
					.getY(), random(1.2, 1.5), random(1.2, 1.5), 0);
			if (location.x == -1 || location.y == -1) {
				return false;
			}
			moveMouse(location, 3, 3);
			if (getMenuItems().get(0).toLowerCase().contains(
					action.toLowerCase())) {
				clickMouse(true);
				return true;
			} else {
				clickMouse(false);
				return atMenu(action);
			}
		} catch (final Exception e) {
			return false;
		}
	}

	public int check() {
		if (isInPolygon(Out)) {
			return 0;
		} else if (!isInPolygon(Out) && distanceTo(new RSTile(1889, 3164)) < 30) {
			return 100;
		} else if (isInPolygon(B_Death)) {
			return 1;
		} else if (isInPolygon(R_Death)) {
			return 2;
		} else if (distanceTo(new RSTile(1933, 3245)) < 2) { // East grave
			return 3;
		} else if (distanceTo(new RSTile(1842, 3218)) < 2) { // West grave
			return 4;
		} else if (getMyPlayer().getInteracting() != null) {
			return 100;
		}
		return 101;
	}

	public String disc() {
		/* Used profisher's and changed it a little. */
		String html = "<html>";
		html += "<body>";
		html += "<center>";
		html += "<b><font size=\"6\" color=\"black\">" + getName() + " v"
				+ getVersion() + "</font><br>";
		html += "<font size=\"5\" color=\"black\">By: !@!@!</b><br><br><br><br></font>";
		html += "<tr><td><center>";
		html += "</center></td></tr>";
		html += "</center></body>";
		html += "</html>";

		return html;
	}

	public boolean isInPolygon(final Polygon p) {
		return p.contains(getMyPlayer().getLocation().getX(), getMyPlayer()
				.getLocation().getY());
	}

	@Override
	public int loop() {

		if (RSInterface.getChildInterface(211, 3).getAbsoluteX() > 20) {
			atInterface(RSInterface.getChildInterface(211, 3));
			return random(1200, 1800);
		}

		if (getMyPlayer().getAnimation() == 836) {
			return random(18000, 20000);
		}

		if (RSInterface.getInterface(228).getChild(2).isValid()) {
			atInterface(RSInterface.getChildInterface(228, 2));
			return random(1200, 1800);
		}

		switch (check()) {
		case 0: // outside of game
			final RSObject Portal = getNearestObjectByID(42031); // portal
			if (Portal == null) {
				break;
			}
			if (!tileOnScreen(Portal.getLocation())) {
				walkTileMM(Portal.getLocation());
				waitWhileMoving();
			}
			atPortal(Portal.getLocation(), "Join");
			waitWhileMoving();
			return random(1600, 2100);

		case 1: // blue start room
			if (tileOnScreen(new RSTile(1815, 3225))) {
				if (!atDoorTile(new RSTile(1815, 3225), "E", "Pass")) {
					turnCamera();
				}
				waitWhileMoving();
				return random(1200, 1800);
			} else {
				walkTileMM(randomizeTile(new RSTile(1815, 3225), 2, 2));
				waitWhileMoving();
				return random(1200, 1800);
			}

		case 2: // red start room
			if (tileOnScreen(new RSTile(1959, 3239))) {
				if (!atDoorTile(new RSTile(1959, 3239), "W", "Pass")) {
					turnCamera();
				}
				waitWhileMoving();
				return random(1200, 1800);
			} else {
				walkTileMM(randomizeTile(new RSTile(1959, 3239), 2, 2));
				waitWhileMoving();
				return random(1200, 1800);
			}

		case 3: // look down
			final RSObject eastGrave = getNearestObjectByID(42013, 42016);
			if (eastGrave == null) {
				return random(100, 900);
			}
			if (tileOnScreen(eastGrave.getLocation())) {
				if (!atDoorTile(eastGrave.getLocation(), "N", "Pass")) {
					turnCamera();
				}
				waitWhileMoving();
				return random(1200, 1800);
			} else {
				walkTileMM(eastGrave.getLocation());
				waitWhileMoving();
				return random(1200, 1800);
			}

		case 4: // look down
			final RSObject westGrave = getNearestObjectByID(42014, 42017);
			if (westGrave == null) {
				return random(100, 900);
			}
			if (tileOnScreen(westGrave.getLocation())) {
				if (!atDoorTile(westGrave.getLocation(), "S", "Pass")) {
					turnCamera();
				}
				waitWhileMoving();
				return random(1200, 1800);
			} else {
				walkTileMM(westGrave.getLocation());
				waitWhileMoving();
				return random(1200, 1800);
			}

		case 100: // OUT OF game antiban
			final int x = random(0, 10);
			switch (x) {
			case 1:
				turnCamera();
				break;
			case 2:
				if (random(0, 3) == 1) {
					tab(true);
				} else {
					tab(false);
				}
				break;
			}
			return random(500, 1000);

		case 101: // IN GAME antiban
			final int a = random(0, 15);
			switch (a) {
			case 1:
				turnCamera();
				break;
			case 2:
				if (random(0, 3) == 1) {
					tab(true);
				} else {
					tab(false);
				}
				break;
			case 3:
				walkRandomTile();
				break;
			}
			return random(500, 1000);
		}

		return random(400, 700);
	}

	@Override
	public void onFinish() {
		Bot.getEventManager().removeListener(this);
	}

	@Override
	public boolean onStart(final Map<String, String> args) {
		return true;
	}

	public void serverMessageRecieved(final ServerMessageEvent e) {
		if (e.getMessage().contains("If you die,")) {
			wait(random(14000, 18000));
		}
	}

	public void tab(final boolean stupid) {
		final int[] nonStupidTabs = { Constants.TAB_CLAN,
				Constants.TAB_FRIENDS, Constants.TAB_INVENTORY,
				Constants.TAB_MUSIC, Constants.TAB_OPTIONS, Constants.TAB_STATS };
		if (stupid) {
			final int i = random(0, 14);
			if (getCurrentTab() != i) {
				openTab(i);
			}
		} else if (!stupid) {
			final int i = random(0, nonStupidTabs.length - 1);
			if (getCurrentTab() != i) {
				openTab(i);
			}
		}
	}

	public boolean turnCamera() {
		try {
			setCameraAltitude(true);
			int newCamera = getCameraAngle() + random(0, 270);
			if (newCamera >= 360) {
				newCamera -= 360;
			}
			setCameraRotation(newCamera);
		} catch (final Exception e) {
			return false;
		}
		return true;
	}

	public void waitWhileMoving() {
		wait(random(500, 700));
		while (getMyPlayer().isMoving()) {
			wait(random(100, 300));
		}
	}

	public void walkRandomTile() {
		final RSTile t = new RSTile(getMyPlayer().getLocation().getX()
				+ random(-16, 16), getMyPlayer().getLocation().getY()
				+ random(-16, 16));
		if (t.isValid() && canReach(t, false)) {
			walkTileMM(t);
			waitWhileMoving();
		}
	}

}